/************************************************************************
 *				SRLOS Team CopyRight
 *@file		mem_mmu_page.h
 *@author	bloceanc
 *@date		7/15/2010
 *@note		virtual memory page management(page managerment)
 ************************************************************************/

#ifndef	_MEM_MMU_PAGE_H_
#define	_MEM_MMU_PAGE_H_

#include "commdef.h"

// already define and set register in boot loader. can't change the value!
#define	MMU_DOMAIN_USR	0x0	// 不检查权限
#define	MMU_DOMAIN_SYS	0x1 // 检查权限

// AP permission control.do not modify this value!
#define	MMU_PAGE_AP_READONLY			0x0
#define	MMU_PAGE_AP_SYSTEM				0x1 
#define	MMU_PAGE_AP_USER				0x3

// AP marsk
#define MMU_PAGE_AP_READONLY_MASK		0xfffff00f

/*
 * WARNING: we must resid the FLPT index to 4, because we fill 4 records for FLPT ervery time!
 * 			and we must make sure that FLPT record will be filled contains the record virtual
 * 			address mapped. so, we  "start_idx = index &~3"
 */
#define	MMU_CREATE_PAGE_MAPPING_FIRST(__phy_base__,__physical__,__virtual__,__domain__)	\
{	\
	unsigned int *flpt = (unsigned int *)COMM_MMU_SYSTEMPAGE_ADDRESS_PHY2VIR(__phy_base__);	\
	unsigned int __physical_tmp__ = 0;	\
	unsigned int i, flpt_count = 4;		\
	unsigned int flpt_startidx = ((unsigned int)((unsigned int)__virtual__) >> 20)&~(0x3);	\
	if(((unsigned int)__physical__)&0x400)	\
	{	\
		system_faital_error();	\
	}	\
	__physical_tmp__ = ((unsigned int)__physical__)&0xfffffc00;	\
	for(i = 0; i < flpt_count; i++)		\
		flpt[flpt_startidx + i] = (__physical_tmp__ + (i << 10)) |(0<<9)|(__domain__<<5)|(1<<4)|(0<<3)|(0<<2)|1;	\
	k_cp15_TLBFlush();	\
}

#define MMU_CREATE_PAGE_MAPPING_SECOND(__phy_base__,__physical__,__virtual__,__ap__,__cache__,__buf__)	\
{	\
	unsigned int *flpt = (unsigned int *)COMM_MMU_SYSTEMPAGE_ADDRESS_PHY2VIR(__phy_base__);	\
	unsigned int __flp_idx__ 	= ((unsigned int)__virtual__)>>20;	\
	unsigned int *__snd_addr_vir__ = 0;	\
	unsigned int __snd_idx__	= 0;	\
	unsigned int __physical_tmp__ = 0;	\
	if((flpt[__flp_idx__]&0x3) != 1)	\
	{	\
		system_faital_error();	\
	}	\
	__snd_addr_vir__ = (unsigned int *)COMM_MMU_SYSTEMPAGE_ADDRESS_PHY2VIR(flpt[__flp_idx__]&0xfffffc00);	\
	__snd_idx__ = (((unsigned int)__virtual__)<< 12)>>24;	\
	if(__snd_addr_vir__[__snd_idx__]&0x3)	\
	{	\
		system_faital_error();	\
	}	\
	__physical_tmp__ = ((unsigned int)__physical__)&0xfffff000;	\
	__snd_addr_vir__[__snd_idx__] = __physical_tmp__|((__ap__)<<10)|((__ap__)<<8)|((__ap__)<<6)|((__ap__)<<4)|((__cache__)<<3)|((__buf__)<<2)|2;	\
	k_cp15_TLBFlush();	\
}

// get physical address of virtual page
#define	MMU_PAGE_PHYSICALADDRESS(__phy_base__,__virtual__,__physical__)	\
{	\
	unsigned int *flpt = (unsigned int *)COMM_MMU_SYSTEMPAGE_ADDRESS_PHY2VIR(__phy_base__);	\
	unsigned int *slpt = (unsigned int *)COMM_MMU_SYSTEMPAGE_ADDRESS_PHY2VIR((flpt[((unsigned int)__virtual__)>>20]&0xfffffc00));	\
	__physical__ = slpt[(((unsigned int)__virtual__)<<12)>>24]&0xfffff000;	\
}

// only clean second level page info
#define	MMU_DESTORY_PAGE_MAPPING_SECOND(__phy_base__,__virtual__)	\
{	\
	unsigned int *flpt = (unsigned int *)COMM_MMU_SYSTEMPAGE_ADDRESS_PHY2VIR(__phy_base__);	\
	unsigned int *slpt = (unsigned int *)COMM_MMU_SYSTEMPAGE_ADDRESS_PHY2VIR((flpt[((unsigned int)__virtual__)>>20]&0xfffffc00));	\
	slpt[(((unsigned int)__virtual__)<<12)>>24] &= 0x0;	\
}

// get page type: first level page or second level page
#define	MMU_PAGEMAPPING_PAGETYPE(__phy_base__,__virtual__,__result__)	\
{	\
	unsigned int *flpt = (unsigned int *)COMM_MMU_SYSTEMPAGE_ADDRESS_PHY2VIR(__phy_base__);	\
	__result__ = flpt[((unsigned int)__virtual__)>>20]&0x3;	\
}

// page fault type define

#define	PAGE_FAULT_TYPE_VECTOR	0x0
#define PAGE_FAULT_TYPE_ALGIN1	0x1
#define PAGE_FAULT_TYPE_ALGIN3	0x3
#define PAGE_FAULT_TYPE_EXTRANS_FIRST	0xc
#define	PAGE_FAULT_TYPE_EXTRANS_SECOND	0xe
#define PAGE_FAULT_TYPE_TRANS_PAGE		0x7
#define PAGE_FAULT_TYPE_DOMAIN_PAGE		0xb
#define PAGE_FAULT_TYPE_PERMISSION_PAGE 0xf
#define PAGE_FAULT_TYPE_LINEFETCH_PAGE  0x6
#define PAGE_FAULT_TYPE_NONLINFECTCH_PAGE 0xa

#endif	/** _MEM_MMU_PAGE_H_ */

